package com.future.handler;

import com.future.exception.BusinessException;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;


@Component
public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
    // 日志记录器
    private static final Logger logger = LoggerFactory.getLogger(CustomAsyncExceptionHandler.class);

    @Override
    public void handleUncaughtException(@NotNull Throwable throwable, @NotNull Method method, @NotNull Object... params) {
        try {
            // 1. 构建异常详情信息
            String errorMsg = buildErrorMessage(throwable, method, params);

            // 2. 记录异常日志（建议使用ERROR级别，便于监控）
            logger.error(errorMsg, throwable); // 注意：这里要传入throwable，否则堆栈信息会丢失

            // 3. 根据异常类型进行特殊处理（可选）
            handleSpecificException(throwable);

        } catch (Exception e) {
            logger.error("处理异步任务异常时发生错误", e);
        }
    }

    /**
     * 构建详细的错误信息
     */
    private String buildErrorMessage(Throwable throwable, Method method, Object[] params) {
        StringBuilder sb = new StringBuilder();
        sb.append("【异步任务异常】")
                .append("时间：").append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
                .append("，方法：").append(method.getDeclaringClass().getName()).append("#").append(method.getName())
                .append("，参数：").append(formatParams(params))
                .append("，异常信息：").append(throwable.getMessage());
        return sb.toString();
    }

    /**
     * 格式化方法参数（避免敏感信息泄露）
     */
    private String formatParams(Object[] params) {
        if (params == null || params.length == 0) {
            return "无";
        }
        StringBuilder paramStr = new StringBuilder();
        for (Object param : params) {
            // 注意：如果参数包含敏感信息（如密码），需要进行脱敏处理
            paramStr.append(param).append(", ");
        }
        return paramStr.substring(0, paramStr.length() - 2);
    }

    /**
     * 根据异常类型进行特殊处理
     */
    private void handleSpecificException(Throwable throwable) {
        // 处理空指针异常
        if (throwable instanceof NullPointerException) {
            logger.warn("异步任务发生空指针异常，可能是参数传递错误");
        }
        // 处理数据库异常
        else if (throwable.getMessage().contains("Database error")) {
            logger.warn("异步任务发生数据库异常，可能是连接问题");
        }
        // 处理业务异常
        else if (throwable instanceof BusinessException) {
            logger.warn("异步任务发生业务异常：" + throwable.getMessage());
        } else if (throwable instanceof RuntimeException) {
            logger.warn("异步任务发生运行时异常：" + throwable.getMessage());
        }
        if(throwable instanceof IllegalArgumentException){
            logger.warn("异步任务发生非法参数异常：" + throwable.getMessage());
        }
        // 其他异常类型...
    }

    /**
     * 发送告警通知（实际项目中可集成短信、邮件、企业微信等）
     */
    private void sendAlertNotification(String errorMsg) {
        // 示例：仅打印告警信息（实际项目中替换为真实告警逻辑）
        // 注意：告警频率需要控制，避免告警风暴
        logger.warn("【异步任务告警】" + errorMsg);

        // 实际实现示例：
        // 1. 调用短信接口发送告警
        // 2. 调用邮件服务发送详细日志
        // 3. 推送告警到企业微信/钉钉群
    }
}
